/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Multicast entry storage header file.
 * \author Antti Maula <antti.maula@tkk.fi>
 */
#ifndef GIMNETAP_MULTICASTTABLE_H_
#define GIMNETAP_MULTICASTTABLE_H_

#include "idmap.h"
//#include "apmulticastframe.h"
#include <inttypes.h>
#include <time.h>

/** Entry for a single subscriber.
 *
 */
typedef struct SMulticastSubscriber
{
  uint32_t subscriber_id;    ///< Subscriber nodeid
  time_t last_update_s;        ///< Last update in seconds
} TMulticastSubscriberEntry;


typedef enum EnumMulticastType {
  KMulticastTypeClosed          = 0x00,
  KMulticastTypePublic          = 0x01,
  KMulticastTypePrivate         = 0x02
} EMulticastType;


/** Multicast table entry (one per reserved ID)
 *
 */
typedef struct SMulticastTableEntry
{
  // Setup
  uint32_t multicast_id;           ///< The id itself (also stored in hash table, this is for convenience)
  uint32_t owner_id;               ///< NodeID of entry owner (creator)
  uint64_t owner_key;              ///< Key for controlling the entry (required for ctrl access)
  uint64_t access_key;             ///< Key for subscribing   
  EMulticastType type;             ///< Multicast type in use.

  // Runtime
  TIDMap subscribers;              ///< Subscriber table
} TMulticastTableEntry;


/// Add a type definition to allow using "module" related iterator names on application level.
typedef TIDMapEntryIterator TMulticastSubscriberIterator;



////////////////// MulticastTable functions
void multicasttableInit(const int maxMulticastIds, const int maxSubscribers);
void multicasttableDeinit(void);

uint32_t multicasttableGetUniqueMulticastId(void);
int multicasttableCreateEntry(const uint32_t multicast_id, TMulticastTableEntry **newentryptr);

TMulticastTableEntry *multicasttableFindEntry(const uint32_t multicast_id);
int multicasttableDeleteEntry(const uint32_t multicast_id);


# warning Need table iteration feature to be able to walk through all tables while searching for tables where a certain (failed) nodeid is registered!
#if 0
long unsigned int multicasttableGetMulticastTableCount(void);
void multicasttableGetMulticastTableIterator(TMulticastTableIterator *iter);
TMulticastTableEntry *multicasttableEntryGetNextMulticastTable(TMulticastSubscriberIterator *iter);
#endif




/////////////////// MulticastTableEntry functions
int multicasttableEntryAddSubscriber(TMulticastTableEntry *entry, 
                                     uint32_t subscriber_id);

const TMulticastSubscriberEntry *multicasttableEntryFindSubscriber(const TMulticastTableEntry *entry, 
                                                                   uint32_t subscriber_id);

int multicasttableEntryDeleteSubscriber(TMulticastTableEntry *entry, 
                                        uint32_t subscriber_id);

long unsigned int multicasttableEntryGetSubscriberCount(const TMulticastTableEntry *entry);
void multicasttableEntryGetSubscriberIterator(const TMulticastTableEntry *entry, 
                                              TMulticastSubscriberIterator *iter);
TMulticastSubscriberEntry *multicasttableEntryGetNextMulticastSubscriberEntry(const TMulticastTableEntry *entry, 
                                                                              TMulticastSubscriberIterator *iter);


#endif
